# -*- encoding: utf-8 -*-

# Copyright 2010 István Szentandrási
# <etude-music-player@googlegroups.com>

# This file is part of Etude.
#
# Etude is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as 
# published by the Free Software Foundation, either version 3 
# of the License, or (at your option) any later version.
#
# Etude is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Etude. If not, see <http://www.gnu.org/licenses/>.

import gobject

from common import *

class Playlist(gobject.GObject):

    """
    Wrapper class around the xmms_playlist_* functions
    """

    def __init__(self, client):
        self.__gobject_init__()
        self.client = client
        self.repeat = PLAYLIST_REPEAT_NONE
        self.client.connect("e_configval_changed", self.repeat_changed)

    def set_repeat(self, rep = None):
        """
        Set the playlist repeat. for the rep value use on of:
        PLAYLIST_REPEAT_NONE
        PLAYLIST_REPEAT_ONE,
        PLAYLIST_REPEAT_ALL
        constants
        """
        rep_all = u"0"
        rep_one = u"0"
        if rep == None:
            self.set_repeat((self.repeat+1)%3)
            return
        if rep == PLAYLIST_REPEAT_ONE:
            rep_one = u"1"
        elif rep == PLAYLIST_REPEAT_ALL:
            rep_all = u"1"
        self.client.config.set(u'playlist.repeat_all', rep_all)
        self.client.config.set(u'playlist.repeat_one', rep_one)

    def get_repeat(self):
        return self.repeat

    def repeat_changed(self, widget, key, value):
        rep_all = u"0"
        rep_one = u"0"
        try:
            if key == u'playlist.repeat_all':
                rep_all = value
                rep_one = self.client.config[u'playlist.repeat_one']
            elif key == u'playlist.repeat_one':
                rep_one = value
                rep_all = self.client.config[u'playlist.repeat_all']
            else:
                return False
            if (rep_one == u"1") and (rep_all == u"1"):
                #self.set_repeat( PLAYLIST_REPEAT_ONE)
                return False
            elif rep_one == u"1":
                self.repeat = PLAYLIST_REPEAT_ONE
            elif rep_all == u"1":
                self.repeat = PLAYLIST_REPEAT_ALL
            else:
                self.repeat = PLAYLIST_REPEAT_NONE
            self.client.emit("e_playlist_repeat_changed", self.repeat)
        except KeyError:
            pass
        return False
    
    @check_wait(False)
    @check_fast(True)
    def list_entries(self, playlist = None, cb =None, cb_args = {}):
        """
        get the list of ids in the playlist
        """
        return self.client.xmms.playlist_list_entries(playlist, lambda result: self._list_entries(result, cb, cb_args))

    @check_result_error(True)
    def _list_entries(self, result, cb, cb_args):
        if hasattr(cb, '__call__'):
            cb(result.value(), **cb_args)
        return False
    
    @check_wait(False)
    @check_fast(True)
    @check_cb_None()
    def set_next(self, index, cb = None, play=False):
        """
        set the next song to be played. Index defines the songs position in the playlist
        """
        res = self.client.xmms.playlist_set_next(index, cb)
        if play:
            self._set_next_play()
        return res

    @check_wait(False)
    @check_fast(True)
    @check_cb_None()
    def set_next_rel(self, rel, cb = None, play=False):
        """
        same as set next, but the position is relative to the current index
        """
        res = self.client.xmms.playlist_set_next_rel(rel, cb)
        if play:
            self._set_next_play()
        return res
        
    def _set_next_play(self):
        if self.client.playback.status == PB_PAUSE:
            self.client.playback.play()
        self.client.playback.tickle()
        if self.client.playback.status == PB_STOP:
            self.client.playback.play()

    @check_cb_None()
    @check_fast(True)
    @check_wait(False)
    def add_id(self, id, playlist = None, cb = None):
        """
        Add medialib id to the playlist
        """
        return self.client.xmms.playlist_add_id(id, playlist, cb)
    
    @check_cb_None()
    @check_fast(True)
    @check_wait(False)
    def add_url(self, url, playlist = None, cb = None):
        """
        add an url to playable media
        """
        return self.client.xmms.playlist_add_url(url, playlist, cb)

    @check_cb_None()
    @check_fast(True)
    @check_wait(False)
    def add_encoded(self, url, playlist = None, cb = None):
        """
        add an encoded url to playable media
        """
        return self.client.xmms.playlist_add_encoded(url, playlist, cb)

    @check_cb_None()
    @check_fast(True)
    @check_wait(False)
    def radd(self, url, playlist = None, cb = None):
        """
        add recursively a directory
        """
        return self.client.xmms.playlist_radd(url, playlist, cb)
    
    @check_cb_None()
    @check_fast(True)
    @check_wait(False)
    def radd_encoded(self, url, playlist = None, cb = None):
        """
        add recursively a directory encoded
        """
        return self.client.xmms.playlist_radd_encoded(url, playlist, cb)

    @check_cb_None()
    @check_fast(True)
    @check_wait(False)
    def insert_encoded(self, pos, url, playlist = None, cb = None):
        """
        insert medialib encoded url to the playlist
        """
        return self.client.xmms.playlist_insert_encoded(pos, url, playlist, cb)
    
    @check_cb_None()
    @check_fast(True)
    @check_wait(False)
    def rinsert_encoded(self, pos, url, playlist = None, cb = None):
        """
        insert medialib encoded url to the playlist
        """
        return self.client.xmms.playlist_rinsert_encoded(pos, url, playlist, cb)
    
    @check_cb_None()
    @check_fast(True)
    @check_wait(False)
    def rinsert(self, pos, url, playlist = None, cb = None):
        """
        insert medialib encoded url to the playlist
        """
        return self.client.xmms.playlist_rinsert(pos, url, playlist, cb)

    @check_cb_None()
    @check_fast(True)
    @check_wait(False)
    def insert_id(self, pos, id, playlist = None, cb = None):
        """
        insert medialib id
        """
        return self.client.xmms.playlist_insert_id(pos, id, playlist, cb)
    
    @check_cb_None()
    @check_fast(True)
    @check_wait(False)
    def insert_url(self, pos, url, playlist = None, cb = None):
        """
        insert an url
        """
        return self.client.xmms.playlist_insert_url(pos, url, playlist, cb)
    
    @check_cb_None()
    @check_fast(True)
    @check_wait(False)
    def remove_entry(self, pos, playlist = None, cb = None):
        """
        remove an entry at pos
        
        NOTE: when removing multiple entrys, be aware that the positions are changing
        """
        return self.client.xmms.playlist_remove_entry(pos, playlist, cb)

    @check_cb_None()
    @check_fast(False)
    @check_wait(False)
    def clear(self, playlist = None, cb = None):
        """
        clear the playlist
        """
        return self.client.xmms.playlist_clear(playlist, cb)

    @check_cb_None()
    @check_fast(False)
    @check_wait(False)
    def shuffle(self, playlist = None, cb = None):
        """
        shuffle the playlist
        """
        return self.client.xmms.playlist_shuffle(playlist, cb)

    @check_cb_None()
    @check_fast(True)
    @check_wait(False)
    def move(self, cur_pos, new_pos, playlist = None, cb = None):
        """
        move a song in the playlist from position cur_pos to position new_pos
        """
        return self.client.xmms.playlist_move(cur_pos, new_pos, playlist, cb)

    @check_cb_None()
    @check_fast(False)
    @check_wait(False)
    def sort(self, props, playlist = None, cb = None):
        """
        props is a list of properties see XMEP_ constants
        for descending order prepend "-" to the beginning of the property
        """
        return self.client.xmms.playlist_sort(props, playlist, cb)

    def current_active(self, cb = None, cb_args = {}):
        """
        return the current active position in the active playlist
        """
        if cb == None:
            return None
        callb = lambda result: self._current_active(result, cb, cb_args)
        self.client.xmms.playlist_current_active(callb)
    
    @check_result_error(True)
    def _current_active(self, result, cb, cb_args):
        if not hasattr(cb, '__call__'):
            return False
        self.current_playlist = result.value()
        cb(result.value(), **cb_args)
        return False

    @check_cb_None()
    @check_fast(False)
    @check_wait(False)
    def add_collection(self, coll, order, playlist = None, cb = None):
        """
        add a collection to the playlist
        """
        return self.client.xmms.playlist_add_collection(coll, order, playlist, cb)

    @check_cb_None()
    @check_fast(True)
    @check_wait(False)
    def load(self, playlist, cb = None):
        """
        Make a playlist active
        """
        return self.client.xmms.playlist_load(playlist, cb)
            
    @check_cb_None()
    @check_fast(False)
    @check_wait(False)
    def create(self, playlist_name, cb = None):
        """
        create a new playlist
        """
        return self.client.xmms.playlist_create(playlist_name, cb)

